﻿using FrameworkCore.Modules.Engines;
using Microsoft.Extensions.Logging;
using FrameworkCore.Events;

namespace Infrastructure.Services;

/// <summary>
/// 表示事件发布器的实现
/// </summary>
public partial class EventPublisher : IEventPublisher
{
    #region Methods

    /// <summary>
    /// 异步发布事件给消费者
    /// </summary>
    /// <typeparam name="TEvent">事件的类型</typeparam>
    /// <param name="event">事件对象</param>
    /// <returns>表示异步操作的任务</returns>
    public virtual async Task PublishAsync<TEvent>(TEvent @event)
    {
        // 获取所有的事件消费者
        var consumers = EngineContext.Current.ResolveAll<IConsumer<TEvent>>().ToList();

        foreach (var consumer in consumers)
        {
            try
            {
                // 尝试处理发布的事件
                await consumer.HandleEventAsync(@event);
            }
            catch (Exception exception)
            {
                // 记录错误，我们使用嵌套的 try-catch 防止可能的循环调用（如果出现错误）
                try
                {
                    var logger = EngineContext.Current.Resolve<ILogger>();
                    if (logger == null)
                        return;

                    logger.LogError(exception.Message, exception);
                }
                catch
                {
                    // 忽略异常
                }
            }
        }
    }

    /// <summary>
    /// 同步发布事件给消费者
    /// </summary>
    /// <typeparam name="TEvent">事件的类型</typeparam>
    /// <param name="event">事件对象</param>
    public virtual void Publish<TEvent>(TEvent @event)
    {
        // 获取所有的事件消费者
        var consumers = EngineContext.Current.ResolveAll<IConsumer<TEvent>>().ToList();

        foreach (var consumer in consumers)
        {
            try
            {
                // 尝试处理发布的事件
                consumer.HandleEventAsync(@event).Wait();
            }
            catch (Exception exception)
            {
                // 记录错误，我们使用嵌套的 try-catch 防止可能的循环调用（如果出现错误）
                try
                {
                    var logger = EngineContext.Current.Resolve<ILogger>();
                    if (logger == null)
                        return;

                    logger.LogError(exception.Message, exception);
                }
                catch
                {
                    // 忽略异常
                }
            }
        }
    }

    #endregion
}
